﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using com.dz.ht.common;
using System.Data;
using System.Threading;
namespace com.dz.ht.components
{
    public class VIPBookCollectManager
    {
        DataManger m_db_mgr = new DataManger();

        //线程数组
        Thread[] m_thd_arr = null;

        //总的需要收集的书籍
        DataSet m_ds = null;

        //文件读写
        FileManager m_file_mgr = new FileManager();

        //每条线程负责的记录条数
        int m_per_thread_count = 0;

        /// <summary>
        /// 要获取的书籍
        /// </summary>
        public string BookSql { get; set; }

        /// <summary>
        /// 触发发送消息的事件
        /// </summary>
        public event SendMsgEventHandler SendMsg;

        #region 消息回送
        /// <summary>
        /// 发送消息到客户端
        /// </summary>
        /// <param name="i_msg"></param>
        private void SendMsg2Client(string i_msg)
        {
            SendMsgEventArgs e = new SendMsgEventArgs();
            e.Msg = i_msg;

            if (SendMsg != null)
            {
                SendMsg(this, e);
            }

        }

        #endregion
        public void StartVIPCollect()
        {
            SendMsg2Client("收集章节信息开始...");
            try
            {

                    m_ds = m_db_mgr.GetVIPBookList();

                    if (m_ds == null || m_ds.Tables[0].Rows.Count <= 0)
                        return;

                    int t_total_count = m_ds.Tables[0].Rows.Count;
                    m_thd_arr = new Thread[AppConfig.ThreadCount];
                    m_per_thread_count = t_total_count / AppConfig.ThreadCount;
                    for (int index = 0; index < AppConfig.ThreadCount; index++)
                    {
                        Thread t_thd = new Thread(ThreadCollect);
                        t_thd.Name = string.Format("book_{0}", index);
                        m_thd_arr[index] = t_thd;

                        t_thd.Start(index);
                    }

                    for (int index = AppConfig.ThreadCount * m_per_thread_count; index < t_total_count; index++)
                    {
                        CollectSingleBook(m_ds.Tables[0].Rows[index]);
                    }
                  
            }
            catch (Exception ex)
            {
                LogHelper.Error("收集VIP书籍失败" + ex.ToString());
            }
        }

        /// <summary>
        /// 收集指定sql的书籍
        /// </summary>
        public void StartVipBookList()
        {
            SendMsg2Client("收集章节信息开始...");

            if (!string.IsNullOrEmpty(BookSql))
            {
                try
                {
                    DataSet ds = m_db_mgr.QueryData(BookSql.Trim());

                    if (ds != null && ds.Tables[0].Rows.Count > 0)
                    {
                        for (int index = 0; index < ds.Tables[0].Rows.Count; index++)
                        {
                            CollectSingleBook(ds.Tables[0].Rows[index]);
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error("获取书籍列表失败" + ex.ToString());
                }

            }
        }


        public void CollectVipBookNormalChapter()
        {
            string t_str_sql = "select bookId,chapterUrl,lastUpdateChapterName,bookCategoryId from tbbook a where not exists(select 1 from tbbookchapter b where a.bookid=b.bookid)";
            try
            {
                m_ds = m_db_mgr.QueryData(t_str_sql);
                int t_total_count = m_ds.Tables[0].Rows.Count;
                m_thd_arr = new Thread[AppConfig.ThreadCount];
                m_per_thread_count = t_total_count / AppConfig.ThreadCount;
                for (int index = 0; index < AppConfig.ThreadCount; index++)
                {
                    Thread t_thd = new Thread(ThreadCollectNormalChapater);
                    t_thd.Name = string.Format("book_{0}", index);
                    m_thd_arr[index] = t_thd;

                    t_thd.Start(index);
                }

                for (int index = AppConfig.ThreadCount * m_per_thread_count; index < t_total_count; index++)
                {
                    CollectNormalChapter(m_ds.Tables[0].Rows[index]);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("收集vip书籍的普通章节失败" + ex.ToString());
            }
        }

        private void CollectNormalChapter(DataRow i_book_row)
        {
            IBookObject t_obj = new com.dz.ht.components.book.site_1.CollectBookManager();

            try
            {
                List<BookChapterInfo> t_chapter_list_source = t_obj.CollectChapterList(i_book_row["chapterUrl"].ToString());
                string t_last_update_chapter_name = i_book_row["lastUpdateChapterName"] == null ? "" : i_book_row["lastUpdateChapterName"].ToString();

                int t_chapter_index = 0;

                int t_chapter_count = 0;

                string t_chapter_content = string.Empty;

                if (t_chapter_list_source != null && t_chapter_list_source.Count > 0)
                {
                    SendMsg2Client(string.Format("地址：{0} 收集到{1}个章节..", i_book_row["chapterUrl"].ToString(), t_chapter_list_source.Count));

                    if (!string.IsNullOrEmpty(t_last_update_chapter_name))
                    {
                        t_chapter_index = t_chapter_list_source.FindIndex(delegate(BookChapterInfo t_chapter_info)
                        {
                            return t_chapter_info.ChapterName == t_last_update_chapter_name;
                        });
                    }
                }
                if (t_chapter_index < 0)
                    t_chapter_index = 0;

                long t_book_id = 0;
                long t_chapter_id = 0;


                if (!long.TryParse(i_book_row["bookId"].ToString(), out t_book_id))
                    t_book_id = 0;

                BookChapterInfo t_chapter = null;

                for (int index = t_chapter_index; index < t_chapter_list_source.Count; index++)
                {
                    t_chapter = t_chapter_list_source[index];

                    t_chapter.BookId = t_book_id;
                    t_chapter.SiteId = (int)Consts.Site.qidian;

                    if (t_chapter.IsVip == false)
                    {
                        t_chapter_content = t_obj.CollectChapterContent(t_chapter_list_source[index].Comfrom);
                        t_chapter_content = NetSiteCatchManager.ReplaceContent(t_chapter_content);
                        t_chapter_count++;
                        //如果章节为空
                        if (string.IsNullOrEmpty(t_chapter_content))
                        {
                            t_chapter_content = t_obj.CollectChapterContent(t_chapter_list_source[index].Comfrom);
                            t_chapter_content = NetSiteCatchManager.ReplaceContent(t_chapter_content);
                            t_chapter_count++;

                        }

                    }
                   
                    
                        //章节入库
                        t_chapter.WordsCount = t_chapter_content.Length;
                        //章节信息保存到数据库
                        t_chapter_id = m_db_mgr.InsertBookChapter(t_chapter, t_chapter.ChapterName);

                        //章节内容保存到磁盘
                        if (t_chapter_id > 0)
                        {
                            m_file_mgr.WriteBookContent(i_book_row["bookCategoryId"].ToString(), t_book_id, t_chapter_id, t_chapter_content);

                        }
                    //没有章节
                    if (string.IsNullOrEmpty(t_chapter_content))
                    {
                        m_db_mgr.UpdateChapterStatus(t_book_id, t_chapter_id);
                    }
                   
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("收集普通章节失败" + ex.ToString());
            }
        }

        /// <summary>
        /// 收集小说章节
        /// </summary>
        /// <param name="i_thd_index"></param>
        private void ThreadCollectNormalChapater(object i_thd_index)
        {
            int t_thd_index = (int)i_thd_index;

            int t_total_count = m_ds.Tables[0].Rows.Count;

            for (int index = t_thd_index * m_per_thread_count; index < (t_thd_index + 1) * m_per_thread_count; index++)
            {
                CollectNormalChapter(m_ds.Tables[0].Rows[index]);
            }


        }


        /// <summary>
        /// 收集小说章节
        /// </summary>
        /// <param name="i_thd_index"></param>
        private void ThreadCollect(object i_thd_index)
        {
            int t_thd_index = (int)i_thd_index;

            int t_total_count = m_ds.Tables[0].Rows.Count;

            for (int index = t_thd_index * m_per_thread_count; index < (t_thd_index + 1) * m_per_thread_count; index++)
            {
                CollectSingleBook(m_ds.Tables[0].Rows[index]);
            }


        }

        /// <summary>
        /// 收集一本小说
        /// </summary>
        /// <param name="i_book_row"></param>
        private void CollectSingleBook(DataRow i_book_row)
        {
            IBookObject t_obj = new com.dz.ht.components.book.site_1.CollectBookManager();

            try
            {
                List<BookChapterInfo> t_chapter_list_source = t_obj.CollectChapterList(i_book_row["chapterUrl"].ToString());


                string t_last_update_chapter_name = i_book_row["lastUpdateChapterName"] == null ? "" : i_book_row["lastUpdateChapterName"].ToString();

                int t_chapter_index = 0;

                int t_vip_chapter_count = 0;
                int t_chapter_count = 0;

                string t_chapter_content = string.Empty;

                bool t_is_compared = false;

                if (t_chapter_list_source != null && t_chapter_list_source.Count > 0)
                {
                    SendMsg2Client(string.Format("地址：{0} 收集到{1}个章节..", i_book_row["chapterUrl"].ToString(), t_chapter_list_source.Count));

                    if (!string.IsNullOrEmpty(t_last_update_chapter_name))
                    {
                        t_chapter_index = t_chapter_list_source.FindIndex(delegate(BookChapterInfo t_chapter_info)
                        {
                            t_is_compared = CompareChapterName(t_chapter_info.ChapterName, t_last_update_chapter_name);
                            if (t_is_compared == false)
                            {
                                t_is_compared = CompareChapterName(t_last_update_chapter_name, t_chapter_info.ChapterName);
                            }
                            return t_is_compared;
                        });
                    }
                }
                if (t_chapter_index < 0)
                    t_chapter_index = 0;

                long t_book_id = 0;
                long t_chapter_id = 0;


                if (!long.TryParse(i_book_row["bookId"].ToString(), out t_book_id))
                    t_book_id = 0;

                BookChapterInfo t_chapter = null;

                string t_html = NetSiteCatchManager.ReadUrl(i_book_row["searchUrl"].ToString(), Encoding.GetEncoding(i_book_row["siteEncoding"].ToString()));
                MatchCollection t_ma = null;

                if (!string.IsNullOrEmpty(t_html))
                {
                    t_ma = Regex.Matches(t_html, i_book_row["regChapterList"].ToString(), RegexOptions.IgnoreCase | RegexOptions.Compiled);
                    if (t_ma != null && t_ma.Count > 0)
                    {
                        SendMsg2Client(string.Format("从搜索地址：{0} 得到 {1} 个章节..", i_book_row["searchUrl"].ToString(), t_ma.Count));
                    }
                    else
                    {
                        m_db_mgr.UpdateBookSearchError(t_book_id, (int)Consts.VipErrorType.VIPRegError);
                        SendMsg2Client(string.Format("请检查 {0} 地址..没得到章节信息", i_book_row["searchUrl"].ToString()));

                        SendMsg2Client(string.Format("章节内容为 {0}", t_html));

                        //重复一次
                        t_html = NetSiteCatchManager.ReadUrl(i_book_row["searchUrl"].ToString().Trim(), Encoding.GetEncoding(i_book_row["siteEncoding"].ToString()));
                        t_ma = Regex.Matches(t_html, i_book_row["regChapterList"].ToString(), RegexOptions.IgnoreCase | RegexOptions.Compiled);
                    }
                }
                else
                {
                    m_db_mgr.UpdateBookSearchError(t_book_id, (int)Consts.VipErrorType.UrlError);
                }

                for (int index = t_chapter_index; index < t_chapter_list_source.Count; index++)
                {
                    t_chapter = t_chapter_list_source[index];

                    t_chapter.BookId = t_book_id;
                    t_chapter.SiteId = (int)Consts.Site.qidian;

                    if (t_chapter.IsVip == false)
                    {
                        t_chapter_content = t_obj.CollectChapterContent(t_chapter_list_source[index].Comfrom);
                        t_chapter_content = NetSiteCatchManager.ReplaceContent(t_chapter_content);
                        t_chapter_count++;
                        //如果章节为空
                        if (string.IsNullOrEmpty(t_chapter_content))
                        {
                            t_chapter_content = CollectChapterFromDBSite(t_ma, i_book_row, t_chapter);
                           
                        }

                    }
                    else
                    {
                        t_chapter_content = CollectChapterFromDBSite(t_ma, i_book_row, t_chapter);

                      
                    }
                    if (!string.IsNullOrEmpty(t_chapter_content) && t_chapter_content.Length > 150)
                    {
                        if (t_chapter.IsVip)
                        {
                            if (!Regex.IsMatch(t_chapter_content, "[\u4E00-\u9FA5]", RegexOptions.IgnoreCase | RegexOptions.Compiled))
                            {
                                break;
                            }
                            t_vip_chapter_count++;
                        }
                        //章节入库
                        t_chapter.WordsCount = t_chapter_content.Length;
                        //章节信息保存到数据库
                        t_chapter_id = m_db_mgr.InsertBookChapter(t_chapter, t_chapter.ChapterName);

                        //章节内容保存到磁盘
                        if (t_chapter_id > 0)
                        {
                            m_file_mgr.WriteBookContent(i_book_row["bookCategoryId"].ToString(), t_book_id, t_chapter_id, t_chapter_content);
                            SendMsg2Client(string.Format("从地址：{0} 收集 {1} 章节内容,章节内容字数：{2}", t_chapter.Comfrom, t_chapter.ChapterName, t_chapter_content.Length));
                        }
                    }
                }

                if (t_vip_chapter_count == 0)
                {
                    m_db_mgr.UpdateBookSearchError(t_book_id, (int)Consts.VipErrorType.NotVIPChapter);
                }

                SendMsg2Client(string.Format("收集到 {0} 个VIP章节,{1} 个普通章节", t_vip_chapter_count,t_chapter_count));
            }
            catch (Exception ex)
            {
                LogHelper.Error("收集小说信息失败" + ex.ToString());
            }
        }

        /// <summary>
        /// 从数据库配置的站点获取章节
        /// </summary>
        private string CollectChapterFromDBSite(MatchCollection i_ma, DataRow i_book_row, BookChapterInfo i_chapter)
        {
            string t_html = string.Empty;
            if (i_ma == null || i_ma.Count <= 0)
                return string.Empty;
            try
            {
                string t_chapter_url = GetVipChpaterUrl(i_ma, i_chapter.ChapterName);

                if (string.IsNullOrEmpty(t_chapter_url))
                {
                    SendMsg2Client(string.Format("检查比较章节名称的方式是否有问题,没得到章节地址,章节名称：{0}", i_chapter.ChapterName));
                    return string.Empty;
                }

                string t_chapter_content = string.Empty;

                if (!t_chapter_url.StartsWith("http") && !t_chapter_url.StartsWith("/"))
                {
                    t_chapter_url = i_book_row["searchUrl"].ToString().Substring(0, i_book_row["searchUrl"].ToString().LastIndexOf("/") + 1) + t_chapter_url;
                }

                if (t_chapter_url.StartsWith("/"))
                {
                    t_chapter_url = i_book_row["siteDomain"].ToString() + t_chapter_url;
                }

                i_chapter.Comfrom = t_chapter_url;
                t_html = NetSiteCatchManager.ReadUrl(t_chapter_url, Encoding.GetEncoding(i_book_row["siteEncoding"].ToString()));

                if (!string.IsNullOrEmpty(t_html))
                {
                    Match t_mc_content = Regex.Match(t_html, i_book_row["regChapter"].ToString().Trim(), RegexOptions.IgnoreCase | RegexOptions.Compiled);

                    if (t_mc_content != null && t_mc_content.Groups.Count > 0)
                    {
                        t_chapter_content = t_mc_content.Groups[1].Value.ToString();
                        if (i_book_row["forbitWords"] != null)
                        {
                            t_chapter_content = Regex.Replace(t_chapter_content, i_book_row["forbitWords"].ToString(), "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                            if (string.IsNullOrEmpty(t_chapter_content))
                                return string.Empty;
                            t_chapter_content = NetSiteCatchManager.ReplaceContent(t_chapter_content);
                            t_chapter_content = string.Format("document.write('{0}');", t_chapter_content);
                            i_chapter.WordsCount = t_chapter_content.Length;
                        }
                    }

                    
                }


                return t_chapter_content;
            }
            catch (Exception ex)
            {
                LogHelper.Error("获取其他站点章节失败" + ex.ToString());
                return string.Empty;
            }
        }

        /// <summary>
        /// 获取vip章节的地址
        /// </summary>
        /// <param name="i_mc"></param>
        /// <returns></returns>
        private string GetVipChpaterUrl(MatchCollection i_ma, string i_chapter_name)
        {
            string t_chapter_url = string.Empty;
       
            foreach (Match t_mc in i_ma)
            {
                if (CompareChapterName(i_chapter_name, t_mc.Groups[2].Value.ToString()))
                {
                    t_chapter_url = t_mc.Groups[1].Value.ToString();
                    break;
                }
            }
           
            return t_chapter_url;
        }


        /// <summary>
        /// 判断是否是相同的章节
        /// </summary>
        /// <param name="i_chapter_source"></param>
        /// <param name="i_chapter_target"></param>
        /// <returns></returns>
        private bool CompareChapterName(string i_chapter_source, string i_chapter_target)
        {
            if (i_chapter_source.Equals(i_chapter_target))
                return true;

            //去掉空格
            i_chapter_source = Regex.Replace(i_chapter_source, "\\s", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            i_chapter_source = Regex.Replace(i_chapter_source, "[【】（），！？(),!?;\\.；、……]", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            i_chapter_target = Regex.Replace(i_chapter_target, "\\s", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            i_chapter_target = Regex.Replace(i_chapter_target, "[【】（），！？(),!?;；\\.、……]", "", RegexOptions.IgnoreCase | RegexOptions.Compiled);
           
            if (i_chapter_source.IndexOf(i_chapter_target) > -1 || i_chapter_target.IndexOf(i_chapter_source) > -1)
                return true;

            return false;
        }
    }
}
